import { Component } from 'react';
import styles from '../replay/style.less';
import zoomInImg from '@/assets/camera/zoom_in.png';
import zoomOutImg from '@/assets/camera/zoom_out.png';

class CameraTimeRule extends Component {
  constructor(props) {
    super(props);
    this.state = {
      height: 65, // 容器高度
      width: 120, // 容器宽度
      canvasHeight: 50, // 画布 高度
      canvasWidth: 120, // 画布宽度
      background: '#000000', // 画布背景
      color: false, //
      markColor: '#FFCC33', // 横线颜色
      rulerWrap: null, // 画布dom
      canvas: null,  // 画布
      cxt: null, // 画布环境
      initX: 0, // 鼠标初始化值
      initXTemp: 0, // 鼠标初始化值临时
      endX: 0, // 鼠标最终值
      isMouseDown: false, // 鼠标是否按下
      timeType: 1, //  放缩类型
      bigGridTime: 0, // 每个格子的时间
      gridTotal: 0, // 总共有多少个格子
      offsetTime: 0, // 偏移时间
      offsetPx: 0, // 偏移像素
      offsetPxLast: 0, // 最终偏移像素
      curMouseX: 0, // 鼠标移动值
      callbackTime: '', // 字符串 选中时间
      callbackTimestamp: 0 // 选中  时间戳
    };
  }

  async componentDidMount() {
    this.props.onRef(this);
    const rulerWrap = document.getElementById('rulerText'); // 获取容器
    rulerWrap.style.height = this.state.height < 50 ? `${50}px` : `${this.state.height}px`;

    const winWidth = rulerWrap.offsetWidth; // 容器宽度

    const canvas = rulerWrap.getElementsByTagName('canvas')[0]; // 获取容器下的canvas标签

    const cxt = canvas.getContext('2d');
    let devicePixelRatio = 1;
    if (window.devicePixelRatio) {
      devicePixelRatio = window.devicePixelRatio;
    }
    const canvasWidth = winWidth * window.devicePixelRatio;
    const canvasHeight = this.state.height * window.devicePixelRatio;
    canvas.width = canvasWidth;
    canvas.height = canvasHeight;
    cxt.scale(devicePixelRatio, devicePixelRatio);
    canvas.style.transformOrigin = 'left top';
    await this.setStateAsync({
      width: winWidth,
      canvasWidth,
      canvasHeight,
      canvas,
      cxt,
    });
    this.changeTimeType(this.state.timeType)
    this.drawRuler(0);
    const that = this;
    // // 手指按下  暂不支持手势
    // canvas.addEventListener('touchstart', async function(e) {
    //   console.log("touchstart")
    //   console.log(e)
    //   await that.setStateAsync({
    //     initX: e.targetTouches[0].pageX,
    //   });
    // }, false);
    //
    // // 手指滑动
    // canvas.addEventListener('touchmove', async function(e) {
    //   console.log("touchmove")
    //   console.log(e)
    //   await that.setStateAsync({
    //     endX: e.targetTouches[0].pageX,
    //   });
    //   that.moveEvent();
    // }, false);
    //
    // // 手指抬起
    // canvas.addEventListener('touchend', async function(e) {
    //   console.log("touchend")
    //   console.log(e)
    //   await that.setStateAsync({
    //     lastX: that.state.count,
    //   });
    //   that.overEvent();
    // }, false);

    // 鼠标按下
    canvas.addEventListener('mousedown', async function(e) {
      if(that.canMoveWithCenter(e.layerX)){
        await that.setStateAsync({
          isMouseDown: true,
          initXTemp: e.layerX,
          initX: e.layerX,
        });
      }
    }, false);

    // 鼠标移动
    canvas.addEventListener('mousemove', async function(e) {
      if (!that.state.isMouseDown) {
        await that.setStateAsync({
          curMouseX: e.layerX,
          initX: that.state.initXTemp,
        });
        that.drawRuler(0)
        return false;
      }
      if(that.canMoveWithCenter(that.state.width/2)){
        await that.setStateAsync({
          endX: e.layerX,
        });
        that.moveEvent();
      }
    }, false);

    // 鼠标抬起&离开
    canvas.addEventListener('mouseup', async function(e) {
      await that.setStateAsync({
        isMouseDown: false,
        endX: e.layerX,
      });
      that.overEvent();
    }, false);

    canvas.addEventListener('mouseleave', async function(e) {
      if(that.state.initXTemp === e.pageX){
        return;
      }
      if (that.state.isMouseDown) {
        if(that.canMoveWithCenter(that.state.width/2)){
          await that.setStateAsync({
            isMouseDown: false,
            endX: e.layerX,
          });
          that.overEvent();
        }
      }else{
        await that.setStateAsync({
          curMouseX: 0,
        });
        that.drawRuler(0);
      }
    }, false);
  }

  async componentWillReceiveProps () {
    // todo 防止参数改变不停的执行
    if(this.props.selectDay != null && this.props.selectDay!==this.state.selectDay){
      await this.setStateAsync({
        initX: 0,
        initXTemp: 0,
        endX: 0,
        offsetPx: 0,
        offsetPxLast: 0,
        curMouseX: 0,
        selectDay: this.props.selectDay,
      })
      this.drawRuler(0);
      // 自动播放
      this.autoPlay();
    }else if(this.props.recordList !=null ){
      // this.drawRuler(0);
    }
  }

  /**
   * 自动播放
   */
  autoPlay(){
    this.overEvent()
  }

  async addTime(){
    const {bigGridTime,gridWidth,offsetPxLast,isMouseDown} = this.state;
    const offsetPxTemp = gridWidth/bigGridTime*1;
    if(!isMouseDown){
      await this.setStateAsync({
        offsetPxLast: offsetPxLast - offsetPxTemp,
        offsetPx: offsetPxLast - offsetPxTemp,
      })
      this.drawRuler(0);
    }
  }

  // 手指&鼠标移动事件
  async moveEvent() {
    const {initX,endX,offsetPxLast} = this.state;
    if(endX === initX){
      return;
    }
    const offsetPxTemp = endX - initX;
    await this.setStateAsync({
      offsetPx: offsetPxTemp+offsetPxLast,
    })
    this.drawRuler(0);
  }

  // 手指&鼠标结束事件
  async overEvent() {
    const {initX,endX,offsetPxLast,callbackTime} = this.state;
    const offsetPxTemp =  endX - initX;
    const curCallbackTime = this.getFullTimeForCenter(this.state.width/2,true);
    await this.setStateAsync({
      offsetPxLast: offsetPxLast + offsetPxTemp,
      offsetPx: offsetPxLast + offsetPxTemp,
      curMouseX: 0,
      endX:0,
      initX:0,
      callbackTime: curCallbackTime,
    })
    this.drawRuler(0);
    // 返回最后的值
    if (this.props.selectTime !== undefined && callbackTime !== curCallbackTime) {
        this.props.selectTime(curCallbackTime);
    }
  }

  setStateAsync(state) {
    return new Promise((resolve) => {
      this.setState(state, resolve);
    });
  }

  dateFormat(date,format) {
    const o = {
      "M+" : date.getMonth()+1, // month
      "d+" : date.getDate(),    // day
      "h+" : date.getHours(),   // hour
      "m+" : date.getMinutes(), // minute
      "s+" : date.getSeconds(), // second
      "q+" : Math.floor((date.getMonth()+3)/3),  // quarter
      "S" : date.getMilliseconds() // millisecond
    }
    if(/(y+)/.test(format)) format=format.replace(RegExp.$1,
      (date.getFullYear()+"").substr(4 - RegExp.$1.length));
    for(var k in o)if(new RegExp("("+ k +")").test(format))
      format = format.replace(RegExp.$1,
        RegExp.$1.length==1 ? o[k] :
          ("00"+ o[k]).substr((""+ o[k]).length));
    return format;
  }

  getTimeText(time,hasSecond) {
    let hour = 0;
    let minute = 0;
    let second = 0;
    const day = time/(24*3600);
    second = time%(24*3600);
    if(time<0){
      second = 24*3600 + time%(24*3600);
    }
    let {selectDay} = this.props;
    let curDate = new Date();
    if(selectDay !== null){
      curDate = new Date(Date.parse(selectDay.split(' ')[0].replace(/-/g,   "/")));
    }
    curDate=curDate.setDate(curDate.getDate()+day);
    curDate=new Date(curDate);
    selectDay = this.dateFormat(curDate,'yyyy-MM-dd');
    if (second >= 3600) {
      minute = (second - (second % 60)) / 60;
      hour = parseInt((minute / 60).toString());
      minute = minute % 60;
      /* eslint-disable */
      hour >= 10 ? hour : hour = '0' + hour;
      minute >= 10 ? minute : minute = '0' + minute;
      second = second % 60;
      second >= 10 ? second : second = '0' + second;
      /* eslint-enable */
      if(hasSecond){
        return selectDay+' '+hour + ':' + minute + ':'+ second;
      }
      return hour + ':' + minute;
    }
    if (second < 3600 && second >= 60) {
      hour = '00';
      minute = parseInt((second / 60).toString());
      /* eslint-disable */
      minute >= 10 ? minute : minute = '0' + minute;
      second = second % 60;
      second >= 10 ? second : second = '0' + second;
      /* eslint-enable */
      if(hasSecond){
        return selectDay+' '+hour + ':' + minute + ':'+ second;
      }
      return hour + ':' + minute;
    }
    if (second < 60) {
      hour = '00';
      minute = '00';
      second = parseInt(second);
      second >= 10 ? second : second = '0' + second;
      if(hasSecond){
        return selectDay+' '+hour + ':' + minute + ':'+ second;
      }
      return hour + ':' + minute;
    }
  }

  /**
   * 左侧开始时间的偏移，返回单位ms
   */
  startOffsetTime(timestamp, step) {
    let remainder = timestamp % step;
    return remainder ? step - remainder : 0;
  }

  async changeTimeType(timeType){
    let gridTotal = 12;
    // let bigGridTime = 0;
    // if(timeType === 1){// 2小时间隔
    //   bigGridTime = 7200;
    // }else if(timeType === 2){// 1小时间隔
    //   bigGridTime = 3600;
    // }else if(timeType === 3){// 30分钟间隔
    //   bigGridTime = 1800;
    // }else if(timeType === 4){// 10间隔
    //   bigGridTime = 600;
    // }
    // gridWidth = this.state.width / gridTotal;

    const {offsetPx,offsetPxLast,bigGridTime,gridWidth} = this.state;

    let curBigGridTime = 0;
    if(timeType === 1){// 2小时间隔
      curBigGridTime = 7200;
    }else if(timeType === 2){// 1小时间隔
      curBigGridTime = 3600;
    }else if(timeType === 3){// 30分钟间隔
      curBigGridTime = 1800;
    }else if(timeType === 4){// 10间隔
      curBigGridTime = 600;
    }
    const curGridWidth = this.state.width / gridTotal;
    let  curOffsetPx = offsetPxLast;
    const  centTime = this.getFullTimeForCenter(this.state.width/2,true);
    if(centTime !== undefined){
      const curPx = this.state.width/2;
      const totalPx = curPx - offsetPx;
      const totalSeconds = Math.floor(totalPx * (bigGridTime/gridWidth))
      curOffsetPx = curPx - (totalSeconds/(curBigGridTime/gridWidth));
    }

    await this.setStateAsync({
      bigGridTime: curBigGridTime,
      gridTotal,
      offsetPxLast: curOffsetPx,
      gridWidth: curGridWidth,
      offsetPx: curOffsetPx,
    })
  }

  getFullTimeWithPx(curPx){
    const {bigGridTime,gridWidth,offsetPxLast} = this.state;
    const totalPx = curPx - offsetPxLast;
    const totalSeconds = Math.floor(totalPx * (bigGridTime/gridWidth))
    return this.getTimeText(totalSeconds,true)
  }

  getFullTimeForCenter(curPx,hasSecond){
    const {bigGridTime,gridWidth,offsetPx} = this.state;
    const totalPx = curPx - offsetPx;
    const totalSeconds = Math.floor(totalPx * (bigGridTime/gridWidth))
    return this.getTimeText(totalSeconds,hasSecond)
  }

  canMoveWithCenter(curPx){
    const {bigGridTime,gridWidth,offsetPx} = this.state;
    const totalPx = curPx + offsetPx;
    const totalSeconds = 24*3600 - Math.floor(totalPx * (bigGridTime/gridWidth))
    return true;
    // if(totalSeconds>0&&totalSeconds<24*3600){
    //   return true;
    // }else {
    //   return false;
    // }
  }

  getDateSeconds(dateStr){
    // 选择日期  record 有跨天的情况
    const {selectDay} = this.props;
    if(selectDay===null){
      return 0;
    }
    const selectDate = new Date(Date.parse(selectDay.replace(/-/g,   "/")))
    const curDate = new Date(Date.parse(dateStr.split(' ')[0].replace(/-/g,   "/")));
    let result = 0
    if(selectDate.getTime() >curDate.getTime()){
      result = 0;
    }else if (selectDate.getTime() < curDate.getTime()) {
      result = 24*3600;
    }else{
      const date = new Date(Date.parse(dateStr.replace(/-/g,   "/")))
      result = date.getHours() * 3600 + date.getMinutes() * 60 + date.getSeconds()
    }
    return result;
  }

  // 判断是不是当天的，如果不是当天的，需要做处理
  getDateTimestamp(dateStr){
    const date = new Date(Date.parse(dateStr.replace(/-/g,   "/")))
    return date.getTime();
  }

  getRecordWith(record){
    const startTime = this.getDateSeconds(record.startTime);
    const endTime = this.getDateSeconds(record.endTime);
    const {bigGridTime,gridWidth,offsetPx} = this.state;
    const startPx = Math.floor(startTime*gridWidth/bigGridTime)+offsetPx;
    const endPx = Math.floor(endTime*gridWidth/bigGridTime)+offsetPx;
    return {start:startPx,end:endPx};
  }

  drawRuler(countTemp) {
    const {width,offsetTime,offsetPx,cxt,bigGridTime,gridTotal,gridWidth} = this.state;
    // 清空画布
    cxt.clearRect(0, 0, this.state.canvasWidth, this.state.canvasHeight);
    // 刻度尺背景
    if (this.state.background) {
      cxt.fillStyle = this.state.background;
      cxt.fillRect(0, 0, this.state.canvasWidth, this.state.canvasHeight);
    }

    const pxOffset = offsetPx; // msOffset * pxMs; // 开始的偏移距离 px
    let leftDistance = 0; // 到左侧的距离
    // let leftDistanceTime = 0; // 到左侧的时间
    for (let i = 0; i < gridTotal+1; i++) {
      // console.log(pxOffset+i * gridWidth)
      leftDistance = pxOffset%gridWidth + i * gridWidth; // 距离 = 开始的偏移距离 + 格数 * px/格
      // if(pxOffset<0){
      //   leftDistanceTime = (Math.abs(Math.floor(pxOffset/gridWidth))+i-1) * bigGridTime; // 时间 = 左侧开始时间 + 偏移时间 + 格数 * ms
      // }else {
      //   leftDistanceTime = (Math.abs(Math.floor(pxOffset/gridWidth))+i) * bigGridTime; // 时间 = 左侧开始时间 + 偏移时间 + 格数 * ms
      // }
      cxt.beginPath();
      cxt.save();
      cxt.strokeStyle = this.state.color ? this.state.color : '#bbb';
      cxt.lineWidth = 1;
      cxt.lineCap = 'round';
      cxt.moveTo(leftDistance, Math.floor(this.state.height * 0.7));
      cxt.lineTo(leftDistance, this.state.height);
      cxt.font = '8pt Arial Bold';
      const midText = this.getFullTimeForCenter(leftDistance,false);
      cxt.fillStyle = '#FFFFFF';
      cxt.fillText(midText, leftDistance - cxt.measureText(midText).width / 2, this.state.height*0.7 - 5);

      cxt.stroke();
      cxt.restore();
      cxt.closePath();
    }

    // 中心刻度线
    cxt.beginPath();
    cxt.save();
    cxt.strokeStyle = this.state.markColor;
    cxt.lineWidth = 2;
    cxt.lineCap = 'round';
    cxt.moveTo((this.state.width / 2), 0);
    cxt.lineTo((this.state.width / 2), this.state.height);
    // 绘制中心时间
    const centTime = this.getFullTimeForCenter(this.state.width / 2,true)
    cxt.fillStyle = '#FFFFFF';
    cxt.font = '12pt Arial Bold';
    cxt.fillText(centTime, this.state.width/2 - cxt.measureText(centTime).width / 2, 25);

    // 绘制移动的时间
    if (!this.state.isMouseDown && this.state.curMouseX>0) {
      const curTime = this.getFullTimeWithPx(this.state.curMouseX)
      cxt.fillStyle = '#FFFFFF';
      cxt.font = '8pt Arial Bold';
      cxt.fillText(curTime, this.state.curMouseX - cxt.measureText(curTime).width / 2, 10);
    }

    // 中间两个横线
    cxt.strokeStyle = '#EBE84D'
    cxt.moveTo(0, this.state.height*0.7);
    cxt.lineTo(width, this.state.height*0.7);
    cxt.moveTo(0, this.state.height*0.8);
    cxt.lineTo(width, this.state.height*0.8);

    // 绘制可用时间线
    cxt.fillStyle = '#2eabff';
    const {recordList} = this.props;
    recordList.forEach((item) => {
      const recordData = this.getRecordWith(item)
      if(recordData.end > 0 && recordData.start < width){
        const start = recordData.start;
        const w = recordData.end - recordData.start
        cxt.fillRect(start,this.state.height*0.7,w,this.state.height*0.1);
      }
    })

    cxt.stroke();
    cxt.restore();
    cxt.closePath();
  }

  async handlZoomIn(){
    if(this.state.timeType < 4) {
      await this.setStateAsync({
        timeType: this.state.timeType+1
      })
      this.changeTimeType(this.state.timeType);
      this.drawRuler(0)
    }
  }

  async handlZoomOut(){
    if(this.state.timeType > 1) {
      await this.setStateAsync({
        timeType: this.state.timeType-1
      })
      this.changeTimeType(this.state.timeType);
      this.drawRuler(0)
    }
  }

  render() {
    const {timeType} = this.state;
    return (
      <div className={styles.timeRuleRoot}>
        <div className={styles.timeRule} id={'rulerText'}>
          <canvas id='canvas' style={{width:'100%',height:'100%'}}></canvas>
        </div>
        <div className={styles.timeRuleAction}>
          <img style={{opacity:timeType !==4?1:0.5 }} onClick={(event) =>this.handlZoomIn()}  className={styles.timeRuleImg} src={zoomInImg}/>
          <img style={{opacity:timeType !==1?1:0.5}} onClick={(event) =>this.handlZoomOut()} className={styles.timeRuleImg} src={zoomOutImg}/>
        </div>
      </div>
    );
  }
}

export default CameraTimeRule;
